package com.ishow.noah.widget

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import com.ishow.common.extensions.dp2px
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.min
import kotlin.math.sin

class CanvasEffectsView @JvmOverloads constructor(
    context: Context,
    attributes: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attributes, defStyleAttr) {

    private val paint = Paint()
    private var rectF = RectF()
    private var touchSlideRectF = RectF()

    private var centerPoint = PointF()
    private var innerProgress: Double = -Math.PI / 4

    private lateinit var sweepGradient: SweepGradient

    init {
        setLayerType(LAYER_TYPE_SOFTWARE, null)
        paint.isDither = true
        paint.isAntiAlias = true
        paint.setShadowLayer(5f, 0F, 0F, Color.GREEN)
        paint.color = Color.RED
        paint.style = Paint.Style.STROKE
        paint.strokeWidth = 10F.dp2px()
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        val size = min(w, h) - DEFAULT_PADDING - DEFAULT_PADDING
        rectF.left = (w - size) / 2F
        rectF.top = (h - size) / 2F
        rectF.right = rectF.left + size
        rectF.bottom = rectF.top + size

        centerPoint.x = rectF.centerX()
        centerPoint.y = rectF.centerY()

        val matrix = Matrix()
        matrix.setRotate(-95F, centerPoint.x, centerPoint.y)
        sweepGradient = SweepGradient(centerPoint.x, centerPoint.y, Color.BLUE, Color.RED)
        sweepGradient.setLocalMatrix(matrix)
        paint.shader = sweepGradient
    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawArc(rectF, -90F, 300F, false, paint)
        drawSlide(canvas, innerProgress)
    }

    private fun drawSlide(canvas: Canvas, angle: Double) {
        val radius = rectF.width() / 2
        val calcX = radius * cos(angle)
        val calcY = radius * sin(angle)

        val x = (centerPoint.x + calcX).toFloat()
        val y = (centerPoint.y + calcY).toFloat()

        canvas.drawCircle(x, y, 20F, paint)
        computeTouchRect(x, y)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        if (!isEnabled) {
            return false
        }

        val x = event.x
        val y = event.y
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                return touchSlideRectF.contains(x, y)
            }
            MotionEvent.ACTION_MOVE -> {
                val angle = atan2(y - centerPoint.y, x - centerPoint.x)
                setInnerProgress(angle)
            }

            MotionEvent.ACTION_UP -> {

            }
        }
        return true

    }


    private fun setInnerProgress(angle: Float) {
        innerProgress = angle.toDouble()
        postInvalidate()
    }


    private fun convertAngle(angle: Int): Int {
        return if (angle > -180 && angle < -90) {
            angle + 360 + 90
        } else {
            angle + 90
        }

    }

    private fun computeTouchRect(x: Float, y: Float) {
        touchSlideRectF.left = x - TOUCH_RADIOS
        touchSlideRectF.top = y - TOUCH_RADIOS
        touchSlideRectF.right = x + TOUCH_RADIOS
        touchSlideRectF.bottom = y + TOUCH_RADIOS
    }

    companion object {
        private const val TOUCH_RADIOS = 20
        /**
         * 最大ANGLE
         */
        private const val MAX_ANGLE = 360

        private const val DEFAULT_PADDING = 50F
    }
}